<template>
  <div class="login-form">
    <div class="title">{{ systemStore.title }}</div>
    <el-form
      ref="formRef"
      :model="formData"
      label-position="top"
      :rules="rules"
      hide-required-asterisk
    >
      <el-form-item label="账号" prop="userName">
        <el-input
          v-model="formData.userName"
          placeholder="请输入账号"
          @keyup.enter="handleClickLoginButton"
        />
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input
          v-model="formData.password"
          type="password"
          show-password
          placeholder="请输入密码"
          @keyup.enter="handleClickLoginButton"
        />
      </el-form-item>
      <el-form-item label="验证码" prop="code">
        <div class="flex flex-1">
          <el-input
            class="flex-1 code-input"
            v-model="formData.code"
            placeholder="请输入验证码"
            @keyup.enter="handleClickLoginButton"
            :formatter="handleFormatCode"
          />
          <CanvasCode
            class="canvas-code"
            ref="canvasCode"
            :noise="0"
            :width="120"
            :height="48"
          />
        </div>
      </el-form-item>
      <el-form-item prop="rememberMe">
        <el-checkbox v-model="formData.rememberMe">记住密码</el-checkbox>
      </el-form-item>
      <el-form-item>
        <el-button
          class="login-button"
          type="primary"
          :loading="loading"
          @click="handleClickLoginButton"
        >
          登录
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import useSystemStore from '@/stores/system'
import { onMounted, reactive, ref, useTemplateRef } from 'vue'
import CanvasCode from '@/components/CanvasCode.vue'
import { useRoute, useRouter } from 'vue-router'
import useUserStore from '@/stores/user'
import { FormInstance, FormRules } from 'element-plus'
import { InternalRuleItem, Value } from 'async-validator/dist-types/interface'
import { login } from '@/api/user'
import { SET_TOKEN } from '@/plugins/util'

const defaultHomePath = '/home'

type CanvasCodeType = InstanceType<typeof CanvasCode>
const route = useRoute()
const router = useRouter()
const systemStore = useSystemStore()
const userStore = useUserStore()
const canvasCode = useTemplateRef<CanvasCodeType>('canvasCode')
const formRef = useTemplateRef<FormInstance>('formRef')

const loading = ref(false)
const formData = reactive({
  userName: '',
  password: '',
  code: '',
  rememberMe: true,
})
const rules = ref<FormRules<typeof formData>>({
  userName: { required: true, message: '请输入账号', trigger: 'blur' },
  password: { required: true, message: '请输入密码', trigger: 'blur' },
  code: [
    { required: true, message: '请输入验证码', trigger: 'blur' },
    {
      validator: validatorCode,
      trigger: 'blur',
    },
  ],
})

function validatorCode(
  rule: InternalRuleItem,
  value: Value,
  callback: (error?: string | Error) => void,
) {
  if (canvasCode.value.checkCode(value)) {
    return callback()
  } else {
    return callback(new Error('验证码错误'))
  }
}

function handleFormatCode(value: string) {
  return value.toUpperCase()
}

function handleClickLoginButton() {
  if (loading.value) {
    return
  }
  formRef.value.validate(async (bool: boolean) => {
    if (!bool) {
      formData.password = ''
      formData.code = ''
      canvasCode.value?.resetCode()
      loading.value = false
      return
    }

    loading.value = true
    try {
      const { data } = await login({
        userName: formData.userName,
        password: formData.password,
      })
      if (data.status === 200 && (await userStore.checkUser()) !== 0) {
        SET_TOKEN(data.data.satoken)

        if (formData.rememberMe) {
          localStorage.setItem('rememberMe', 'true')
          localStorage.setItem('userName', formData.userName)
          localStorage.setItem('password', formData.password)
        } else {
          localStorage.removeItem('rememberMe')
          localStorage.removeItem('userName')
          localStorage.removeItem('password')
        }

        if (route.query.redirect) {
          await router.push(route.query.redirect.toString())
        } else {
          await router.push(defaultHomePath)
        }
      }
      loading.value = false
    } catch {
      formData.password = ''
      formData.code = ''
      canvasCode.value?.resetCode()
      loading.value = false
    }
  })
}

onMounted(() => {
  if (localStorage.getItem('rememberMe') === 'true') {
    formData.rememberMe = true
    formData.userName = localStorage.getItem('userName') || ''
    formData.password = localStorage.getItem('password') || ''
  }
})
</script>

<style scoped lang="scss">
.login-form {
  @apply flex-auto;
  @apply flex flex-col justify-center items-center;
}

.title {
  font-family: 'YouSheBiaoTiHei', serif;
  font-size: 36px;
  @apply font-normal;
  @apply mb-5;
}

.el-form {
  width: 400px;

  .el-form-item {
    --el-form-label-font-size: 18px;
    margin-bottom: 20px;

    :deep(.el-form-item__error) {
      padding-top: 5px;
      font-size: 14px;
    }
  }

  :deep(.el-form-item__label) {
    margin-bottom: 16px;
  }

  .el-input {
    --el-input-height: 48px;
    font-size: 16px;
  }

  .code-input {
    :deep(.el-input__wrapper) {
      border-radius: 4px 0 0 4px;
    }
  }

  .canvas-code {
    border-radius: 0 4px 4px 0;
  }

  .el-checkbox {
    --el-checkbox-font-size: 18px;
    --el-checkbox-input-height: 20px;
    --el-checkbox-input-width: 20px;
  }

  .login-button {
    margin-top: 40px;
    width: 100%;
    height: 48px;
    font-size: 20px;
  }
}
</style>
